package com.epam;

public class FunctionCalculation {

	public static void main(String[] args) {

		//all is an object
		//even an expression
		int a = 5;
		System.out.println(Math.sqrt(Math.pow(Math.E, a)-Math.abs(a)));
		Equation e = new Equation(5, 0.001);
		System.out.println(e.getSqrt());
	}

}

class Equation {

	private double x;
	private double accuracy;
	
	private double E_IN_POWER_X;
	private double absX;
	
	public Equation(double x, double accuracy){
		this.absX = (x < 0)? -x: x;
		this.x = x;
		this.accuracy = accuracy;
	}

	double getSqrt() {
		E_IN_POWER_X =  getEInPowerX(x);
		
		double result = (E_IN_POWER_X - absX)/ 2;
		
		while(result - Math.sqrt(E_IN_POWER_X - absX) > accuracy){
			result = 0.5*(result + (E_IN_POWER_X - absX)/ result);
		}

		return result;	
	}

	double getEInPowerX(double arg) {

		double result = 0;
		//only 20! because 21! > 64 bits
		for(int n = 0; n < 21; n++){
			result += getAInPowerN(arg, n)/getFact(n);		
		};
		return result;
	}

	//to avoid using Math.class this function was
	//written
	double getAInPowerN(double arg, int n) {	

		double result = 1;

		for(int i = 0; i < n; i++){
			result *= arg;
		}
		return result;
	}

	long getFact(int n) {	
		return (n == 0) ? 1 : n * getFact(n - 1);
	}

}